home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / dylibload / symfind.c < prev   
C/C++ Source or Header  |  1990-05-01  |  11KB  |  448 lines

  1. /*
  2.  * %M% %I% of %G%
  3.  * %W%
  4.  */
  5. /* begincopyright
  6.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  7.   Use and copying of this software and preparation of derivative works based
  8.   upon this software are permitted. Any distribution of this software or
  9.   derivative works must comply with all applicable United States export
  10.   control laws. This software is made available AS IS, and Xerox Corporation
  11.   makes no warranty about the software, its performance or its conformity to
  12.   any specification. Any person obtaining a copy of this software is requested
  13.   to send their name and post office or electronic mail address to:
  14.     PCR Coordinator
  15.     Xerox PARC
  16.     3333 Coyote Hill Rd.
  17.     Palo Alto, CA
  18.   endcopyright */
  19.  
  20. # include <sys/types.h>
  21. # include <ar.h>
  22. # include <ranlib.h>
  23. # include <nlist.h>
  24.  
  25. # include "xr/UIO.h"
  26. # include "xr/BasicTypes.h"
  27. # include "xr/ThreadsMsg.h"
  28. # include "xr/CommandLine.h"
  29. # include "xr/CommandLoop.h"
  30. # include "xr/libsearch.h"
  31.  
  32. #define USE_SSU_DEFAULT_LIBRARIES    1
  33.  
  34.  
  35. #define DCLCLCE        XR_CLCallEnv clce \
  36.     = (XR_CLCallEnv) XR_GetTopLevelCLCallEnv()
  37.  
  38. #define IFPRINTMSG    if( XR_CLVerbose(XR_VERBOSITY_NORMAL) )
  39. #define IFPRINTERR    if( XR_CLVerbose(XR_VERBOSITY_ERROR) )
  40. #define PRINT        XR_CLMsg
  41. #define PRINTMSG    IFPRINTMSG PRINT
  42. #define PRINTERR    IFPRINTERR PRINT 
  43.  
  44.  
  45. char *XR_malloc();
  46. char *XR_pointerfree_new();
  47. static void XR_lib_close();
  48. char *get_nth_word();
  49.  
  50. # define LIB_OPEN_no_space            -1
  51. # define LIB_OPEN_no_such_library         -2 
  52. # define LIB_OPEN_file_not_found         -3 
  53. # define LIB_OPEN_invalid_archive        -4
  54. # define LIB_OPEN_no_symdef_in_archive        -5
  55. # define LIB_OPEN_stat_failed            -6
  56. # define LIB_OPEN_inconsisten_version        -7
  57.  
  58. static  struct library *libraryList;
  59. static  int libraryListLength;
  60. static  int libraryListMaxLength;
  61. static  struct {
  62.     struct library *libraryList;
  63.     int libraryListLength;
  64.     int libraryListMaxLength;
  65. } libraryListStack[LIB_LIST_STACK_MAX_DEPTH];
  66. static  int libraryListStackDepth;
  67.  
  68.  
  69. /*
  70.  * clear the library list
  71.  */
  72.  
  73. static void
  74. XR_lib_clear()
  75. {
  76.   if (libraryList == 0) {
  77.     libraryListLength = 0;
  78.     libraryListMaxLength = 10;
  79.     libraryList = (struct library *)
  80.             XR_malloc(libraryListMaxLength * sizeof(struct library));
  81.   }
  82.   XR_lib_close();
  83.   libraryListLength = 0;
  84. }
  85.  
  86.  
  87. /*
  88.  * close all library file descriptors, the library list remains unchanged
  89.  */
  90.  
  91. static void
  92. XR_lib_close()
  93. {
  94.   struct library *p;
  95.   
  96.   for (p = &libraryList[0]; p < &libraryList[libraryListLength]; p++) {
  97.     if (p->fildes != -1) {
  98.       XR_Close(p->fildes);
  99.       p->fildes = -1;
  100.       p->ranp = 0;
  101.       p->strp = 0;
  102.     }
  103.   }
  104. }
  105.  
  106.  
  107. /*
  108.  * set the library list to the default list
  109.  */
  110.  
  111. static void
  112. XR_lib_default()
  113. {
  114.   XR_lib_clear();
  115. # if USE_SSU_DEFAULT_LIBRARIES
  116.     libraryList[libraryListLength].libname = "/usr/lib/libpixrect.a";
  117.     libraryList[libraryListLength].fildes = -1;
  118.     libraryListLength++;
  119.     libraryList[libraryListLength].libname = "/usr/lib/libc.a";
  120.     libraryList[libraryListLength].fildes = -1;
  121.     libraryListLength++;
  122.     libraryList[libraryListLength].libname = "/usr/lib/libm.a";
  123.     libraryList[libraryListLength].fildes = -1;
  124.     libraryListLength++;
  125. # endif
  126. }
  127.  
  128.  
  129. /*
  130.  * list the libraries on the library list 
  131.  */
  132.  
  133. static void
  134. XR_lib_list()
  135. {
  136.   struct library *p;
  137.   DCLCLCE;
  138.  
  139.   IFPRINTMSG {
  140.     for (p = &libraryList[0]; p < &libraryList[libraryListLength]; p++) {
  141.       PRINT "%s ", p->libname);
  142.     }
  143.     PRINT "\n");
  144.   }
  145. }
  146.  
  147.  
  148. /*
  149.  * append library to end of library list
  150.  */
  151.  
  152. static void
  153. XR_lib_append(commandString)
  154. char *commandString;
  155. {
  156.   char *libname;
  157.   struct library *p;
  158.   DCLCLCE;
  159.   
  160.   libname = get_nth_word(XR_GetCurrentCommand(), 1);
  161.   if (!libname[0]) {
  162.     PRINTERR "libappend: argument needed\n");
  163.     return;
  164.   }
  165.   if (libraryListLength >= libraryListMaxLength) {
  166.     struct library * newLibraryList = (struct library *) XR_malloc(
  167.       2 * libraryListMaxLength * sizeof(struct library) );
  168.     (void) bcopy(libraryList, newLibraryList,
  169.       libraryListMaxLength * sizeof(struct library));
  170.     libraryList = newLibraryList;
  171.     libraryListMaxLength *= 2;
  172.   }
  173.   p = &libraryList[libraryListLength++];
  174.   p->libname = libname;
  175.   p->fildes = -1;
  176.   XR_lib_list();
  177. }
  178.  
  179.  
  180. /*
  181.  * prepend library to beginning of library list
  182.  */
  183.  
  184. static void
  185. XR_lib_prepend(commandString)
  186. char *commandString;
  187. {
  188.   char *libname;
  189.   struct library *p;
  190.   DCLCLCE;
  191.   
  192.   libname = get_nth_word(XR_GetCurrentCommand(), 1);
  193.   if (!libname[0]) {
  194.     PRINTERR "libprepend: argument needed\n");
  195.     return;
  196.   }
  197.   if (libraryListLength >= libraryListMaxLength)
  198.     libraryList = (struct library *)XR_realloc(libraryList, libraryListMaxLength *= 2);
  199.   for (p = &libraryList[libraryListLength]; p > &libraryList[0]; p--) {
  200.     *p = *(p - 1);
  201.   }
  202.   p->libname = libname;
  203.   p->fildes = -1;
  204.   libraryListLength++;
  205.   XR_lib_list();
  206. }
  207.  
  208.  
  209. /*
  210.  * push the library list down on the stack of library lists
  211.  * the top of the stack is an empty library list
  212.  */
  213.  
  214. static void
  215. XR_lib_push()
  216. {
  217.   int ii;
  218.   DCLCLCE;
  219.   
  220.   if ((ii = libraryListStackDepth) >= LIB_LIST_STACK_MAX_DEPTH) {
  221.     PRINTERR "libpush: library list overflow\n");
  222.     return;
  223.   }
  224.   libraryListStack[ii].libraryList = libraryList;
  225.   libraryListStack[ii].libraryListLength = libraryListLength;
  226.   libraryListStack[ii].libraryListMaxLength = libraryListMaxLength;
  227.   libraryListStackDepth = ii + 1;
  228.   libraryList = 0;
  229.   XR_lib_clear();
  230. }
  231.  
  232.  
  233. /*
  234.  * pop up the stack of library lists
  235.  */
  236.  
  237. static void
  238. XR_lib_pop()
  239. {
  240.   int ii;
  241.   DCLCLCE;
  242.   
  243.   if ((ii = libraryListStackDepth) <= 0) {
  244.     PRINTERR "libpop: library list underflow\n");
  245.     return;
  246.   }
  247.   XR_lib_close();
  248.   --ii;
  249.   libraryList = libraryListStack[ii].libraryList;
  250.   libraryListStack[ii].libraryList = 0;
  251.   libraryListLength = libraryListStack[ii].libraryListLength;
  252.   libraryListMaxLength = libraryListStack[ii].libraryListMaxLength;
  253.   libraryListStackDepth =ii;
  254. }
  255.  
  256.  
  257. /*
  258.  * register pcr commands to manipulate the library list
  259.  */
  260.  
  261. void
  262. XR_lib_init()
  263. {
  264.   typedef void (*registeredProc)();
  265.   static registeredProc
  266.       def = XR_lib_default,
  267.     pop = XR_lib_pop,
  268.     push = XR_lib_push,
  269.     close = XR_lib_close,
  270.     prepend = XR_lib_prepend,
  271.     append = XR_lib_append,
  272.     clear = XR_lib_clear,
  273.     list = XR_lib_list;
  274.  
  275.   XR_register("libdefault", &def,
  276.           "set library list to the default list", 0);
  277.   XR_register("libpop", &pop,
  278.           "pop up the stack of library lists", 0);
  279.   XR_register("libpush", &push,
  280.           "push down the stack of library lists", 0);
  281.   XR_register("libclose", &close,
  282.           "close all libraries to release file descriptors", 0);
  283.   XR_register("libprepend", &prepend,
  284.           "prepend the argument to the beginning of the library list", 0);
  285.   XR_register("libappend", &append,
  286.           "append the argument to the end of the library list", 0);
  287.   XR_register("libclear", &clear,
  288.           "clear the library list", 0);
  289.   XR_register("liblist", &list,
  290.           "list the libraries on the library list", 0);
  291.   XR_lib_default();
  292. }
  293.  
  294.  
  295. # define ok_fread(buf, len, count, fd) \
  296.     if (XR_Read((fd), (buf), (len)*(count)) < 0) { \
  297.       PRINTERR "read error %d\n", XR_GetErrno()); \
  298.       goto Bad; \
  299.     }
  300.  
  301. # define ok_fseek(fd, offset, whence) \
  302.     if (XR_LSeek((fd), (offset), (whence)) < 0) { \
  303.       PRINTERR "lseek error %d\n", XR_GetErrno()); \
  304.       goto Bad; \
  305.     }
  306.  
  307.  
  308. /*
  309.  * open the (ii)th library, return the file descriptor for it.
  310.  * return small negative integers for error conditions
  311.  * (an error message will already have been printed using xr_printf).
  312.  */
  313.  
  314. static XR_Fildes
  315. XR_lib_open(ii)
  316. int ii;
  317. {
  318.   XR_Fildes fd;
  319.   char magicString[SARMAG+1];
  320.   struct ar_hdr symdefHeader;
  321.   char *symdefName;
  322.   struct stat buf;
  323.   int retval, size;
  324.   char *strp;
  325.   struct ranlib *ranp, *ranpMax;
  326.   DCLCLCE;
  327.   
  328.   if (ii >= libraryListLength)
  329.     return ((XR_Fildes)LIB_OPEN_no_such_library);
  330.   if ((fd = libraryList[ii].fildes) == -1) {
  331.     if ((fd = XR_Open(libraryList[ii].libname, O_RDONLY)) < 0) {
  332.       PRINTERR "XR_lib_open: file not found: %s\n",
  333.         libraryList[ii].libname);
  334.       return ((XR_Fildes)LIB_OPEN_file_not_found);
  335.     }
  336.     libraryList[ii].fildes = fd;
  337.     ok_fread(magicString, SARMAG, 1, fd);
  338.     magicString[SARMAG] = 0;
  339.     if (strcmp(magicString, ARMAG)) {
  340.       PRINTERR "XR_lib_open: invalid archive: %s\n",
  341.         libraryList[ii].libname);
  342.       return ((XR_Fildes)LIB_OPEN_invalid_archive);
  343.     }
  344.     ok_fread(&symdefHeader, sizeof(struct ar_hdr), 1, fd);
  345.     symdefName = "__.SYMDEF       ";
  346.     if (strncmp(symdefHeader.ar_name, symdefName, strlen(symdefName))) {
  347.       PRINTERR "XR_lib_open: no symdef in archive: %s\n",
  348.         libraryList[ii].libname);
  349.       return ((XR_Fildes)LIB_OPEN_no_symdef_in_archive);
  350.     }
  351.     if ((retval = XR_FStat(fd, &buf)) < 0) {
  352.       PRINTERR "XR_lib_open: stat failed: %s\n",
  353.         libraryList[ii].libname);
  354.       return ((XR_Fildes)LIB_OPEN_stat_failed);
  355.     }
  356.     if (buf.st_mtime > atoi(symdefHeader.ar_date)) {
  357.       PRINTERR "XR_lib_open: inconsisten version: %s\n",
  358.         libraryList[ii].libname);
  359.       return((XR_Fildes)LIB_OPEN_inconsisten_version);
  360.     }
  361.     ok_fread(&size, sizeof(int), 1, fd);
  362.     libraryList[ii].ranp = ranp = (struct ranlib *)XR_pointerfree_new(size);
  363.     if (ranp == 0)
  364.       return((XR_Fildes)LIB_OPEN_no_space);
  365.     ok_fread(libraryList[ii].ranp, size, 1, fd);
  366.     libraryList[ii].ranpMax = ranpMax = (struct ranlib *)( (int)ranp + size );
  367.     ok_fread(&size, sizeof(int), 1, fd);
  368.     libraryList[ii].strp = strp = XR_pointerfree_new(size);
  369.     if (strp == 0) {
  370.       PRINTERR "XR_lib_open: no space\n");
  371.       return((XR_Fildes)LIB_OPEN_no_space);
  372.     }
  373.     ok_fread(strp, size, 1, fd);
  374.     for (; ranp < ranpMax; ranp++)
  375.       ranp->ran_un.ran_name += (long)strp;
  376.   }
  377.   return (fd);
  378. Bad:
  379.   return (-1);
  380. }
  381.  
  382.  
  383. /*
  384.  * given an undefined symbol, look it up in the library list,
  385.  * return true, a file descriptor for the library,
  386.  * an offset at which the symbol is defined.
  387.  * as additional information return a hint of the type of file the library member is
  388.  * and the name of the library.
  389.  * return false if symbol is not found in any library in the library list.
  390.  */
  391.  
  392. bool
  393. XR_lib_symfind(sym, libfd, liboffset, magic, modulename)
  394. char *sym;
  395. XR_Fildes *libfd;
  396. long *liboffset;
  397. long *magic;
  398. char **modulename;
  399. {
  400.   int libindex;
  401.   XR_Fildes fd;
  402.   struct ranlib *ranp, *ranpMax;
  403.   struct ar_hdr arHdr;
  404.   char *libname, *cp, *cq;
  405.   DCLCLCE;
  406.  
  407.   for (libindex = 0; (fd = XR_lib_open(libindex)) != LIB_OPEN_no_such_library; libindex++) {
  408.     if (fd < 0)
  409.       continue;
  410.     ranpMax = libraryList[libindex].ranpMax;
  411.     for (ranp = libraryList[libindex].ranp; ranp < ranpMax; ranp++) {
  412.       if (strcmp(sym, ranp->ran_un.ran_name) == 0) {
  413.         *libfd = fd;
  414.         *liboffset = ranp->ran_off + sizeof(struct ar_hdr);
  415.         *magic = 0;
  416.     ok_fseek(fd, ranp->ran_off, 0);
  417.     ok_fread(&arHdr, sizeof(struct ar_hdr), 1, fd);
  418.     libname = libraryList[libindex].libname;
  419.     cp = *modulename = XR_pointerfree_new(strlen(libname) + sizeof(arHdr.ar_name) + 3);
  420.     for (cq = libname; *cq; )
  421.       *cp++ = *cq++;
  422.     *cp++ = '(';
  423.     for (cq = arHdr.ar_name; (*cq != ' ') && (cq < &arHdr.ar_name[sizeof(arHdr.ar_name)]); )
  424.       *cp++ = *cq++;
  425.     *cp++ = ')';
  426.     *cp++ = 0;
  427.         return(TRUE);
  428.       }
  429.     }
  430.   }
  431. Bad:
  432.   return(FALSE);
  433. }
  434.  
  435.  
  436. XR_run_symfind()
  437. {
  438.   XR_lib_init();
  439. }
  440.  
  441.  
  442. /* LOG: 
  443.  *  Earsh Wed Nov  2 17:45:25 1988
  444.  *  TJW 3/22/88
  445.  *  tou   Tue Sep 12 15:15:50 1989
  446.  *  Demers, April 16, 1990 8:09:19 am PDT
  447.  */
  448.